/////////// VARIABLES
float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 NormalMatrix;
float4x4 WVP;
float3 CameraPosition;

uniform extern texture Texture;
uniform extern texture PositionTexture;
uniform extern texture VelocityTexture;

float Time;


//////////// SAMPLERS
sampler PositionSampler = sampler_state
{
	Texture = <PositionTexture>;
	MipFilter = None;
    MinFilter = Point;
    MagFilter = Point;
    AddressU  = Clamp;
    AddressV  = Clamp;
};

sampler VelocitySampler = sampler_state
{
	Texture = <VelocityTexture>;
	MipFilter = None;
    MinFilter = Point;
    MagFilter = Point;
    AddressU  = Clamp;
    AddressV  = Clamp;
};

sampler TextureSampler = sampler_state
{
	Texture = <Texture>;
	MipFilter = Linear;
    MinFilter = Linear;
    MagFilter = Linear;
    AddressU  = Wrap;
    AddressV  = Wrap;
};


/////////// INPUTS AND OUTPUTS
struct VertexShaderInput
{    
    float3 Position : POSITION0;
    float4 Color : COLOR;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float4 Color : COLOR;
    float Size: PSIZE;
    float2 TexCoord : TEXCOORD0;
};

struct VertexShaderInputCombine
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
};

struct VertexShaderOutputCombine
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
};

struct PixelShaderOutput
{
	float4 Color : COLOR0;
};



//////// VERTEX SHADER

VertexShaderOutput VertexShaderBasic(VertexShaderInput input)
{
	VertexShaderOutput output = (VertexShaderOutput)0;
	
	float4 position = tex2Dlod(PositionSampler, float4(input.Position.x, input.Position.y, 0,0));
	//float4 position = float4(float4(input.Position.x, input.Position.y, 0, 1));
	position.w = 1.0;
	
	output.Position = mul(position, WVP);
	output.TexCoord = float2(0,0);
	output.Color = input.Color;
	output.Size = input.Position.z;
	
	return output;
}

VertexShaderOutput VertexShaderBasic2(VertexShaderInput input)
{
	VertexShaderOutput output = (VertexShaderOutput)0;
	
	float4 position = tex2Dlod(PositionSampler, float4(input.Position.x, input.Position.y, 0,0));
	//float4 position = float4(float4(input.Position.x, input.Position.y, 0, 1));
	position.w = 1.0;
	
	output.Position = mul(position, WVP);
	output.TexCoord = float2(0,0);
	output.Color = input.Color;
	float l = sqrt(position.x*position.x + position.y*position.y + position.z*position.z);
	output.Size = input.Position.z*l+30;
	
	return output;
}

VertexShaderOutputCombine VertexShader2D(VertexShaderInputCombine input)
{
	VertexShaderOutputCombine output = (VertexShaderOutputCombine)0;
	
	output.Position = input.Position;
	output.TexCoord = input.TexCoord;

	return output;
}

///////// PIXEL SHADER

PixelShaderOutput PixelVelocityUpdate(VertexShaderOutputCombine input)
{
	PixelShaderOutput output;
	output.Color = tex2D(VelocitySampler, input.TexCoord.xy);
	output.Color.w = 1;
	output.Color.xyz *= 0.98;
	return output;
}

PixelShaderOutput PixelVelocityUpdate2(VertexShaderOutputCombine input)
{
	PixelShaderOutput output;
	
	float3 pos = tex2D(PositionSampler, input.TexCoord.xy).xyz;
	float l = sqrt(pos.x*pos.x + pos.y*pos.y + pos.z*pos.z);
	float3 v = ((float3(0,0,0)-pos)/(l*l))/500;
	
	if ( l > 0.5f )
	{
		output.Color.xyz = v;
	} else if ( l < 0.05f )
	{
		output.Color.xyz = -v;
	} else 
	{
		output.Color = tex2D(VelocitySampler, input.TexCoord.xy)*1.01f;
	}
	
	output.Color.w = 1;
	
	return output;
}

float4 PixelPositionUpdate(VertexShaderOutputCombine input) : COLOR0
{
	//PixelShaderOutput output;
	float4 ss = tex2D(PositionSampler, input.TexCoord) + tex2D(VelocitySampler, input.TexCoord);
	ss.w = 1.0;
	return ss;
}

float4 PixelShaderBasicCopy(VertexShaderOutputCombine input) : COLOR0
{
	return tex2D(PositionSampler, input.TexCoord);
}


float4 PixelShaderBasic2(VertexShaderOutputCombine input) : COLOR0
{
	float4 t1 = tex2D(PositionSampler, input.TexCoord);
	float4 t2 = tex2D(VelocitySampler, input.TexCoord);
	float4 c = 0;
	c.x = t1.x + t2.x;
	c.y = t1.y + t2.y;
	c.z = t1.z + t2.z;
	c.w = 1.0;
	
	return c;
}

PixelShaderOutput PixelShaderBasicParticles(VertexShaderOutput input)
{
	PixelShaderOutput output;
	//output.Color = input.Color;
	output.Color = tex2D(TextureSampler, input.TexCoord) * input.Color;
	//output.Color.r *= input.Color.r;	//output.Color = float4(1, input.TexCoord.x, input.TexCoord.y, 1);
	
	return output;
}




technique VelocityUpdate
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShader2D();
        PixelShader = compile ps_3_0 PixelVelocityUpdate();
    }
}

technique VelocityUpdate2
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShader2D();
        PixelShader = compile ps_3_0 PixelVelocityUpdate2();
    }
}

technique PositionUpdate
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShader2D();
        PixelShader = compile ps_3_0 PixelPositionUpdate();
    }
}

technique ParticleRender
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShaderBasic();
        PixelShader = compile ps_3_0 PixelShaderBasicParticles();
    }
}

technique ParticleRender2
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShaderBasic2();
        PixelShader = compile ps_3_0 PixelShaderBasicParticles();
    }
}

technique Copy
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShader2D();
        PixelShader = compile ps_3_0 PixelShaderBasicCopy();
    }
}

technique Add2
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 VertexShader2D();
        PixelShader = compile ps_3_0 PixelShaderBasic2();
    }
}







